package com.yang.mall.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yang.mall.dto.LiveOrderMasterDTO;
import com.yang.mall.dto.QueryOrderDTO;
import com.yang.mall.dto.QueryStatisticsDTO;
import com.yang.mall.dto.SubmitProductDTO;
import com.yang.mall.entity.LiveOrder;
import com.yang.mall.entity.LiveOrderLine;
import com.yang.mall.entity.Product;
import com.yang.mall.entity.QueryRequest;
import com.yang.mall.exception.OLException;
import com.yang.mall.mapper.LiveOrderMapper;
import com.yang.mall.service.ILiveOrderLineService;
import com.yang.mall.service.ILiveOrderService;
import com.yang.mall.service.ILiveShopCartService;
import com.yang.mall.service.IProductService;
import com.yang.mall.tools.BeanUtils;
import com.yang.mall.tools.DateUtil;
import com.yang.mall.vo.LiveOrderVO;
import com.yang.mall.vo.OrderStatisticsVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * <p>
 * 订单表 服务实现类
 * </p>
 *
 * @author kadorlin
 * @since 2022-10-21
 */
@Service
public class LiveOrderServiceImpl extends ServiceImpl<LiveOrderMapper, LiveOrder> implements ILiveOrderService {
    @Autowired
    private IProductService productService;
    @Autowired
    private ILiveOrderLineService liveOrderLineService;
    @Autowired
    private ILiveShopCartService liveShopCartService;
    /**
     * 提交订单
     * @param liveOrderMasterDTO
     * @author:kadorlin
     * @date:2022/10/24 10:17
     * @return:void
     **/
    @Override
    public LiveOrder submit(LiveOrderMasterDTO liveOrderMasterDTO) {
        LiveOrder liveOrder = BeanUtils.copyBeanProp(liveOrderMasterDTO, LiveOrder.class);
        String orderNum = generate("YY");
        liveOrder.setOrderNum(orderNum);
        this.save(liveOrder);

        ArrayList<LiveOrderLine> liveOrderLines = new ArrayList<>();

        List<SubmitProductDTO> productDTOList = liveOrderMasterDTO.getProductDTOList();

        List<Long> productIds = productDTOList.stream().map(SubmitProductDTO::getProductId).distinct().collect(Collectors.toList());
        Map<Long, Product> productMap = this.productService.getProductByIds(productIds).stream().collect(Collectors.toMap(Product::getProductId, p -> p));
        BigDecimal totalPrice = new BigDecimal("0");

        for (SubmitProductDTO item:productDTOList) {
            Product product = productMap.get(item.getProductId());
            if (Objects.isNull(product)) {
                throw new OLException("商品：" + product.getProductName() + " 已失效～");
            }
            if (item.getQuantity() > product.getStockNum()) {
                throw new OLException("商品：" + product.getProductName() + " 库存不足～");
            }
            LiveOrderLine liveOrderLine = BeanUtils.copyBeanProp(product, LiveOrderLine.class);
            liveOrderLine.setOrderId(liveOrder.getOrderId());
            liveOrderLine.setMemberId(liveOrderMasterDTO.getMemberId());
            liveOrderLine.setOrderNum(orderNum);
            liveOrderLine.setQuantity(item.getQuantity());
            liveOrderLine.setCreateTime(LocalDateTime.now());
            liveOrderLine.setUnitPrice(product.getMarketPrice());
            totalPrice = totalPrice.add(product.getMarketPrice().multiply(new BigDecimal(item.getQuantity().toString())));
            liveOrderLine.setTotalPrice(product.getMarketPrice().multiply(new BigDecimal(item.getQuantity().toString())));
            liveOrderLine.setPayPrice(product.getMarketPrice().multiply(new BigDecimal(item.getQuantity().toString())));
            liveOrderLine.setUpdateTime(LocalDateTime.now());
            liveOrderLine.setPhotoUrl(product.getPhotoUrl());
            liveOrderLines.add(liveOrderLine);
        }
        liveOrderLineService.saveBatch(liveOrderLines);
        liveOrder.setOrderStatus(1);
        liveOrder.setTotalPrice(totalPrice);
        liveOrder.setPayPrice(totalPrice);
        this.updateById(liveOrder);


        //List<Long> shopCartIds = liveOrderMasterDTO.getShopCartIds();
        List<Long> shopCartIds = productDTOList.stream().map(SubmitProductDTO::getId).collect(Collectors.toList());
        if(!CollectionUtils.isEmpty(shopCartIds)){
            this.liveShopCartService.batchRemove(shopCartIds);
        }
        return liveOrder;
    }


    /**
     * 订单列表
     * @param request
     * @author:kadorlin
     * @date:2022/10/24 10:42
     * @return:com.baomidou.mybatisplus.core.metadata.IPage<com.yang.mall.vo.LiveOrderVO>
     **/
    @Override
    public IPage<LiveOrderVO> orderList(QueryOrderDTO request) {
        Page<LiveOrder> page = new Page<>(request.getPageNum(), request.getPageSize());

        QueryWrapper<LiveOrder>  qw = new QueryWrapper<>();
        qw.lambda()
                .like(Objects.nonNull(request.getShopName()),LiveOrder::getShopName,request.getShopName())
                .like(Objects.nonNull(request.getName()),LiveOrder::getName,request.getName())
                .like(Objects.nonNull(request.getOrderNum()),LiveOrder::getOrderNum,request.getOrderNum())
                .eq(Objects.nonNull(request.getOrderStatus()),LiveOrder::getOrderStatus,request.getOrderStatus())
                .eq(Objects.nonNull(request.getMemberId()),LiveOrder::getMemberId,request.getMemberId());
        IPage<LiveOrder> orderIPage = this.page(page, qw);

        return orderIPage.convert(item-> {
            LiveOrderVO liveOrderVO = BeanUtils.copyBeanProp(item, LiveOrderVO.class);
            List<LiveOrderLine> byOrderId = this.liveOrderLineService.findByOrderId(liveOrderVO.getOrderId());
            liveOrderVO.setLiveOrderLineVOS(byOrderId);
            return liveOrderVO;
        });

    }


    /**
     * 订单明细
     * @param orderId
     * @author:kadorlin
     * @date:2022/10/24 10:55
     * @return:com.yang.mall.vo.LiveOrderVO
     **/
    @Override
    public LiveOrderVO detail(Long orderId) {
        QueryWrapper<LiveOrder>  qw = new QueryWrapper<>();
        qw.lambda().eq(LiveOrder::getOrderId,orderId);
        LiveOrder one = this.getOne(qw);
        LiveOrderVO liveOrderVO = BeanUtils.copyBeanProp(one, LiveOrderVO.class);
        List<LiveOrderLine> byOrderId = this.liveOrderLineService.findByOrderId(liveOrderVO.getOrderId());
        liveOrderVO.setLiveOrderLineVOS(byOrderId);
        return liveOrderVO;
    }

    /**
     * @param orderId
     * @author:kadorlin
     * @date:2022/10/24 10:56
     * @return:void
     **/
    @Override
    public void cancel(Long orderId) {
        LiveOrder one = new LiveOrder();
        one.setOrderId(orderId);
        one.setOrderStatus(4);
        this.updateById(one);
    }

    public static String generate(String prefix) {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(prefix);
        stringBuilder.append(DateUtil.formatFullTime(LocalDateTime.now()));
        return stringBuilder.toString();
    }

    /**
     * 订单统计
     * @param queryStatisticsDTO
     * @author:kadorlin
     * @date:2022/10/26 17:47
     * @return:com.yang.mall.vo.OrderStatisticsVO
     **/
    @Override
    public OrderStatisticsVO statistics(QueryStatisticsDTO queryStatisticsDTO) {
        QueryWrapper<LiveOrder>  qw = new QueryWrapper<>();
        qw.lambda()
                .ge(LiveOrder::getCreateTime,queryStatisticsDTO.getStartDate())
                .le(LiveOrder::getCreateTime,queryStatisticsDTO.getEndDate())
                .eq(LiveOrder::getMemberId,queryStatisticsDTO.getMemberId());
        List<LiveOrder> list = this.list(qw);

        OrderStatisticsVO orderStatisticsVO = new OrderStatisticsVO();

        if(CollectionUtils.isEmpty(list)){
            orderStatisticsVO.setTotalPrice(new BigDecimal("0"));
        }else {
            BigDecimal reduce = list.stream().map(LiveOrder::getTotalPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
            orderStatisticsVO.setTotalPrice(reduce);
        }
        return orderStatisticsVO;

    }



}
